const config = require('./config')

const path = require('path')
const chalk = require('chalk')
const gulp = require('gulp')

const rev = require('gulp-rev-dxb') // ！！！！ 修改过源码使用VERSION 版本号 
// 更改源码 gulp-rev-dxb -- (line-112)plugin.manifest = (pth, opts, VERSION) -- (line-136) manifest[originalFile] = originalFile + '?v=' + VERSION;
const VERSION = '2.0';
const revCollector = require('gulp-rev-collector-dxb')
const assetRev = require('gulp-asset-rev')
const runSequence = require('run-sequence')

const gulpif = require('gulp-if')
const htmlmin = require('gulp-htmlmin')
const fileinclude = require('gulp-file-include')
const sass = require('gulp-sass')
const postcss = require('gulp-postcss')
const cleanCSS = require('gulp-clean-css')
const plumber = require('gulp-plumber')
const notify = require('gulp-notify')
const cache  = require('gulp-cache')
const imagemin = require('gulp-imagemin')
const pngquant = require('imagemin-pngquant')
const uglify = require('gulp-uglify')
const eslint = require('gulp-eslint')
const stripDebug = require('gulp-strip-debug')
const babel = require('gulp-babel')
const sequence = require('gulp-sequence')
const zip = require('gulp-zip')
const del = require('del')

// webpack
const webpack = require('webpack')
const webpackStream = require('webpack-stream')
const webpackConfig = require('./webpack.config.js')
const { rename } = require('fs')
const gulpRename = require('gulp-rename')
// server
const browserSync = require('browser-sync').create()
const reload = browserSync.reload

// NODE_ENV
const env = process.env.NODE_ENV || 'development'
const condition = env === 'production'

function respath(dir) {
  return path.join(__dirname, './', dir)
}

function onError(error) {
  const title = error.plugin + ' ' + error.name
  const msg = error.message
  const errContent = msg.replace(/\n/g, '\\A ')

  notify.onError({
    title: title,
    message: errContent,
    sound: true
  })(error)

  this.emit('end')
}

function cbTask(task) {
  return new Promise((resolve, reject) => {
    del(respath('dist'))
    .then(paths => {
      console.log(chalk.green(`
      -----------------------------
        Clean tasks are completed
      -----------------------------`))
      runSequence(task, () => {
        console.log(chalk.green(`
        -----------------------------
          All tasks are completed
        -----------------------------`))
        resolve('completed')
      })
    })
  })
}

gulp.task('html', () => {
  return gulp.src(config.dev.html)
    .pipe(plumber(onError))
    .pipe(fileinclude({
      prefix: '@@',
      basepath: respath('src/include/')
    }))
    .pipe(gulpif(condition, htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      minifyJS: true,
      minifyCSS: true
    })))
    .pipe(gulp.dest(config.build.html))

})

gulp.task('styles', () => {
  return gulp.src(config.dev.styles)
    .pipe(plumber(onError))
    .pipe(sass())
    .pipe(gulpif(condition, cleanCSS({debug: true})))
    .pipe(postcss('./.postcssrc.js'))
    // .pipe(rev())
    .pipe(gulp.dest(config.build.styles))
    // .pipe(rev.manifest()).pipe(gulp.dest('dist/rev/css'))
})
gulp.task('images', () => {
  return gulp.src(config.dev.images)
    .pipe(plumber(onError))
    .pipe(cache(imagemin({
      progressive: true, // 无损压缩JPG图片
      svgoPlugins: [{removeViewBox: false}], // 不移除svg的viewbox属性
      use: [pngquant()] // 使用pngquant插件进行深度压缩
    })))
    // .pipe(rev())
    .pipe(gulp.dest(config.build.images))
    // .pipe(rev.manifest()).pipe(gulp.dest('dist/rev/images'))
})

gulp.task('eslint', () => {
  return gulp.src(config.dev.script)
   .pipe(plumber(onError))
   .pipe(gulpif(condition, stripDebug()))
   .pipe(eslint({ configFle: './.eslintrc' }))
   .pipe(eslint.format())
   .pipe(eslint.failAfterError());
})


const useEslint = config.useEslint ? ['eslint'] : [];
gulp.task('script', useEslint, () => {
  return gulp.src(config.dev.script)
    .pipe(plumber(onError))
    // .pipe(gulpif(condition, babel({
    //   presets: ['env']
    // })))
    .pipe(babel({
      presets: ['env']
    }))
    .pipe(gulpif(config.useWebpack, webpackStream(webpackConfig, webpack)))
    .pipe(gulpif(condition, uglify()))
    // .pipe(rev())
    .pipe(gulp.dest(config.build.script))
    // .pipe(rev.manifest()).pipe(gulp.dest('dist/rev/js'))
    

})

gulp.task('static', () => {
  return gulp.src(config.dev.static)
    .pipe(gulp.dest(config.build.static))
})



// 生成版本map
gulp.task('rev', () => {
  console.log('---------------rev------------------')
  return gulp.src(['dist/static/css/**','dist/static/js/**'])
      .pipe(rev())
      .pipe(rev.manifest({},{},VERSION))
      .pipe(gulp.dest('dist/rev'))
})
// 根据map替换引用
gulp.task('set_version', () => {
  console.log('---------------set_version------------------')
  // 'dist/static/images/**'
  return gulp.src(['dist/rev/**/*.json', 'dist/**/*.html'])
      .pipe(revCollector()) // 根据.json文件 执行文件内js/css名的替换
      .pipe(gulp.dest('dist'))
})
gulp.task('set_version-css-url', () => {
  console.log('---------------set_version-css------------------')
  return gulp.src(['dist/rev/**/*.json', 'dist/static/css/**/*.css'])
      .pipe(revCollector()) // 根据.json文件 执行文件内js/css名的替换
      .pipe(gulp.dest(config.build.styles))
})


gulp.task('clean', () => {
  del('dist/**').then(paths => {
    console.log('Deleted files and folders:\n', paths.join('\n'));
  });
})

gulp.task('watch', () => {
  gulp.watch(config.dev.allhtml, ['html']).on('change', reload)
  gulp.watch(config.dev.styles, ['styles']).on('change', reload)
  gulp.watch(config.dev.script, ['script']).on('change', reload)
  gulp.watch(config.dev.images, ['images']).on('change', reload)
  gulp.watch(config.dev.static, ['static']).on('change', reload)
})

gulp.task('zip', () => {
  return gulp.src(config.zip.path)
  .pipe(plumber(onError))
  .pipe(zip(config.zip.name))
  .pipe(gulp.dest(config.zip.dest))
})

gulp.task('server', () => {
  const task = ['html', 'styles', 'script', 'images', 'static']
  cbTask(task).then(() => {
    browserSync.init(config.server)
    console.log(chalk.cyan('  Server complete.\n'))
    gulp.start('watch')
  })
})

gulp.task('build', (cb) => {
  const task = ['html', 'styles', 'script', 'images', 'static']
  runSequence(
    task,
    ['rev'],
    ['set_version'],
    ['set_version-css-url'], //处理 css引用图片缓存问题
    cb
  )
  // cbTask(task).then(() => {
  //   console.log(chalk.cyan('  Build complete.\n'))

  //   if (config.productionZip) {
  //     gulp.start('zip', () => {
  //       console.log(chalk.cyan('  Zip complete.\n'))
  //     })
  //   }
  // })
})

gulp.task('default', () => {
  console.log(chalk.green(
   `
  Build Setup
    开发环境： npm run dev
    生产环境： npm run build
    执行压缩： gulp zip
    编译页面： gulp html
    编译脚本： gulp script
    编译样式： gulp styles
    语法检测： gulp eslint
    压缩图片： gulp images
    `
  ))
})
